#include <iostream>
#include <string>
#include <cstdio>
#include <ctime>

//#include <GL/glut.h>

#include "objobject.h"
#include "vertex.h"
#include "vertexnormal.h"
#include "triangle.h"
#include "common.h"

using namespace std;

OBJObject::OBJObject() {
	m_vertexCounter = 0;
	m_vertexCount = 0;
	m_triangleCount = 0;
	m_vertexNormalCount = 0;
	m_texcoordsCount = 0;

	m_maxX = 0; m_minX = 0;
	m_maxY = 0; m_minY = 0;
	m_maxZ = 0; m_minZ = 0;
	
	//default = not selected = 0
	m_selected = 0;
}

OBJObject::~OBJObject() {

}

void OBJObject::setUniqName(std::string uniqName) {
	m_uniqName = uniqName;
}

void OBJObject::loadFile(std::string filename) {
	FILE *fp = fopen(filename.c_str(),"r");
	char line[999];
	int vertexCount=0;
	int vertexNormalCount=0;
	int vertexTexCoordCount=0;
	int triangleCount=0;

	float tempx, tempy, tempz;
	float vntempx, vntempy, vntempz;
	float vttempx, vttempy;
	time_t secondsstart;
	time_t secondsend;


    if (fp != NULL)
    {
	m_objobjectFilename = filename;
	std::cout << "adding vertices and faces...\n";
//	std::cout.flush();
	secondsstart = time (NULL);
        while (fgets(line, 99, fp))
        {
		//process vertex coordinates
              if (line[0] == 'v' && line[1] == ' ')
              {
                  //sscanf(line, "%*c %f %f %f", &v[vertexCount].x, &v[vertexCount].y, &v[vertexCount].z);
                  sscanf(line, "%*c %f %f %f", &tempx, &tempy, &tempz);
		m_vertexList.push_back(new Vertex(tempx, tempy, tempz));
		if (tempx > m_maxX) m_maxX = tempx;
		if (tempy > m_maxY) m_maxY = tempy;
		if (tempz > m_maxZ) m_maxZ = tempz;
		
		if (tempx < m_minX) m_minX = tempx;
		if (tempy < m_minY) m_minY = tempy;
		if (tempz < m_minZ) m_minZ = tempz;
		m_vertexList.back()->m_id = vertexCount;
		LOG("added Vertex  " << tempx << " " << tempy << " " << tempz << " to m_vertexList");
                  vertexCount++;
//		std::cout << " progress: " << vertexCount / (m_vertexCount/100) << "\r";
              }


		//process vertex normals
              if (line[0] == 'v' && line[1] == 'n')
              {
                  //sscanf(line, "%*c %f %f %f", &v[vertexCount].x, &v[vertexCount].y, &v[vertexCount].z);
                  sscanf(line, "%*c%*c %f %f %f", &vntempx, &vntempy, &vntempz);
		m_vertexNormalList.push_back(new VertexNormal(vntempx, vntempy, vntempz));
		m_vertexNormalList.back()->m_id = vertexNormalCount;
		LOG("added VertexNormal  " << vntempx << " " << vntempy << " " << vntempz << " to m_vertexNormalList");
                  vertexNormalCount++;
//		std::cout << " progress: " << vertexNormalCount / (m_vertexCount/100) << "\r";
              }

		//process vertex texture coordinates
              if (line[0] == 'v' && line[1] == 't')
              {
                  //sscanf(line, "%*c %f %f %f", &v[vertexCount].x, &v[vertexCount].y, &v[vertexCount].z);
                  sscanf(line, "%*c%*c %f %f", &vttempx, &vttempy);
		m_vertexTexCoordList.push_back(new VertexTexCoord(vttempx, vttempy));
		m_vertexTexCoordList.back()->m_id = vertexTexCoordCount; //
		std::cout << "added VertexTexCoord  " << vttempx << " " << vttempy << " to m_vertexTexCoordList" << std::endl;
                  vertexTexCoordCount++;
              }

		//process faces/triangles
              else if (line[0] == 'f')
              {
		int tempvert1, tempvert2, tempvert3;
		int tempvertnorm1, tempvertnorm2, tempvertnorm3;
		int tempverttexcoord1, tempverttexcoord2, tempverttexcoord3;

                //sscanf for format: f 1 2 4
		if (m_mode == MODE_ONLY_V)
			//f v v v
			sscanf(line, "%*c %d %d %d", &tempvert1, &tempvert2, &tempvert3);

		 //faces must be in format: 1/x 2/y 3/z  where x,y,z is not relevant here
		 //1,2,3 are index numbers of the vertices
		else if (m_mode == MODE_NO_VN) 
			sscanf(line, "%*c   %d %*c %*d     %d %*c %*d    %d %*c %*d", &tempvert1, &tempvert2, &tempvert3);
		else if (m_mode == MODE_NO_VT) 
			sscanf(line, "%*c   %d %*c%*c  %d     %d %*c%*c  %d    %d %*c%*c  %d", 
				&tempvert1, &tempvertnorm1, &tempvert2, &tempvertnorm2, &tempvert3, &tempvertnorm3);
		else if (m_mode == MODE_ALL) 
			sscanf(line, "%*c   %d %*c %d %*c %d      %d %*c %d %*c %d    %d %*c %d %*c %d", 
				&tempvert1, &tempverttexcoord1, &tempvertnorm1, 
				&tempvert2, &tempverttexcoord2, &tempvertnorm2, 
				&tempvert3, &tempverttexcoord3, &tempvertnorm3);
		LOG("f: " << tempvert1 << " " << tempvert2 << " " << tempvert3);
		m_triangleList.push_back(new Triangle(tempvert1, tempvert2, tempvert3, this));
		if (m_mode == MODE_NO_VT) {
			m_triangleList.back()->addNormals(tempvertnorm1, tempvertnorm2, tempvertnorm3);
		}
		if (m_mode == MODE_ALL) {
			m_triangleList.back()->addNormals(tempvertnorm1, tempvertnorm2, tempvertnorm3);
			m_triangleList.back()->addTexCoords(tempverttexcoord1, tempverttexcoord2, tempverttexcoord3);
		} 
                  triangleCount++;
		if ((m_triangleCount/100)>0 && (triangleCount / (m_triangleCount/100))<=100) std::cout << " progress: " << triangleCount / (m_triangleCount/100) << "%\r";
              }
        }
	secondsend = time (NULL);
	std::cout << "\ndone in " << secondsend-secondsstart << " seconds\n";
	std::cout << "m_minX, m_maxX: " << m_minX << ", " << m_maxX << std::endl;
	std::cout << "m_minY, m_maxY: " << m_minY << ", " << m_maxY << std::endl;
	std::cout << "m_minZ, m_maxZ: " << m_minZ << ", " << m_maxZ << std::endl;
    }

    fclose(fp);
}

void OBJObject::analyzeFile(std::string filename) {
	FILE *fp = fopen(filename.c_str(),"r");
	char line[999];
	int vertexCount=0;
	int triangleCount=0;
	int vtCount=0;
	int vnCount=0;

	float tempx, tempy, tempz;
	std::string texturefilename = filename;

    if (fp != NULL)
    {
        while (fgets(line, 99, fp))
        {
		//find vertices
		if (line[0] == 'v' && line[1] == ' ')
		{
			vertexCount++;
		}
		
		//find vertex normals
		if (line[0] == 'v' && line[1] == 'n')
		{
			vnCount++;
		}
		
		//find vertex texture coords
		if (line[0] == 'v' && line[1] == 't')
		{
			vtCount++;
		}

		//find faces/triangles
              else if (line[0] == 'f')
              {
                  triangleCount++;
              }
        }
    }
	INFO("analyzeFile()");
	INFO(" found vertices: " << vertexCount);
	INFO(" found triangles: " << triangleCount);
	INFO(" found vertex normals: " << vnCount);
	INFO(" found vertex texture coords: " << vtCount);
	m_vertexCount = vertexCount;
	m_triangleCount = triangleCount;
	m_vertexNormalCount = vnCount;
	m_texcoordsCount = vtCount;

	//no vertex normals
	if (m_vertexCount > 0 && 
		m_triangleCount > 0 && 
		m_texcoordsCount > 0 &&
		m_vertexNormalCount == 0) {
		INFO("assuming face format: v/vt v/vt v/vt");
		if (getTexFilename(&texturefilename) == true) m_texturefilename = texturefilename;
		m_mode = MODE_NO_VN;
	}
	//v and vt and vn
	else if (m_vertexCount > 0 && 
		m_triangleCount > 0 && 
		m_texcoordsCount > 0 &&
		m_vertexNormalCount > 0) {
		INFO("assuming face format: v/vt/vn v/vt/vn v/vt/vn");
		if (getTexFilename(&texturefilename) == true) m_texturefilename = texturefilename;
		m_mode = MODE_ALL;
	}
	//no textures
	else if (m_vertexCount > 0 && 
		m_triangleCount > 0 && 
		m_texcoordsCount == 0 &&
		m_vertexNormalCount > 0) {
		INFO("assuming face format: v//vn v//vn v//vn");
		m_mode = MODE_NO_VT;
	}
	//no textures and no normals
	else if (m_vertexCount > 0 && 
		m_triangleCount > 0 && 
		m_texcoordsCount == 0 &&
		m_vertexNormalCount == 0) {
		INFO("assuming face format: v v v");
		m_mode = MODE_ONLY_V;
	}


    fclose(fp);
}

int OBJObject::getTexFilename(std::string *str) {
	std::string::iterator texIt = str->end();
	str->replace(texIt-4, str->end(), ".bmp");
	INFO("texture file: " << *str);

	FILE *fp = fopen(str->c_str(),"r");
	if (fp == NULL) {
		ERROR("texture file \"" << *str << "\" not found!");
		return false;
	}
	else  return true;
}

void OBJObject::printVertexList(void) {
	std::list<Vertex*>::iterator it;
	LOG("number of vertexList elements: " << m_vertexList.size());
	for (it=m_vertexList.begin(); it!=m_vertexList.end(); it++) {
		LOG("address: " << *it << " m_id: " << (*it)->m_id);
	}

}

void OBJObject::printVertexNormalList(void) {
	std::list<VertexNormal*>::iterator it;
	LOG("number of vertexNormalList elements: " << m_vertexNormalList.size());
	for (it=m_vertexNormalList.begin(); it!=m_vertexNormalList.end(); it++) {
		LOG("address: " << *it << " m_id: " << (*it)->m_id);
	}

}

void OBJObject::printTriangleList(void) {
	std::list<Triangle*>::iterator it;
	LOG("number of triangleList elements: " << m_triangleList.size());
	for (it=m_triangleList.begin(); it!=m_triangleList.end(); it++) {
//		LOG("address: " << *it << " m_id: " << (*it)->m_id);
		LOG(" triangle:");
		LOG("  vertex1: " << (*it)->m_x1 << " " << (*it)->m_y1 << " " << (*it)->m_z1);
		LOG("  vertex2: " << (*it)->m_x2 << " " << (*it)->m_y2 << " " << (*it)->m_z2);
		LOG("  vertex3: " << (*it)->m_x3 << " " << (*it)->m_y3 << " " << (*it)->m_z3);
	}

}

/**
 * \brief returns the address of vertex with given index
 *
 */
Vertex* OBJObject::getVertex(int index) {
	std::list<Vertex*>::iterator it;
	for (it=m_vertexList.begin(); it!=m_vertexList.end(); it++) {
	//CAUTION: index - 1 is necessary because obj files face/vertex numbering starts
	//counting with 1 instead of 0
		if ((*it)->m_id == index - 1) {
			LOG("vertex(" << index << ") has address " << *it);
			return *it;
		}
	}
	return 0;
}

/**
 * \brief returns the address of vertexNormal with given index
 *
 */
VertexNormal* OBJObject::getNormal(int index) {
	std::list<VertexNormal*>::iterator it;
	for (it=m_vertexNormalList.begin(); it!=m_vertexNormalList.end(); it++) {
	//CAUTION: index - 1 is necessary because obj files face/vertex numbering starts
	//counting with 1 instead of 0
		if ((*it)->m_id == index - 1) {
			LOG("vertexNormal(" << index << ") has address " << *it);
			return *it;
		}
	}
	return 0;
}

/**
 * \brief returns the address of VertexTexCoord with given index
 *
 */
VertexTexCoord* OBJObject::getTexCoord(int index) {
	std::list<VertexTexCoord*>::iterator it;
	for (it=m_vertexTexCoordList.begin(); it!=m_vertexTexCoordList.end(); it++) {
	//CAUTION: index - 1 is necessary because obj files face/vertex numbering starts
	//counting with 1 instead of 0
		if ((*it)->m_id == index - 1) {
			LOG("vertexTexCoord(" << index << ") has address " << *it);
			return *it;
		}
	}
	return 0;
}

int OBJObject::getNumVertices() {
	return m_vertexCounter;
}

std::list<Triangle*> OBJObject::getTriangleList() {
	return m_triangleList;
}

void OBJObject::drawObject(void) {
	std::list<Triangle*>::iterator itTri;
	LOG("trianglelist size: " <<  m_triangleList.size());
	//this was a bug! don't ever use it again!
	//because OBJObjects are also part of OBJAnimObjects and
	//so they disable textures if there's an animation with no textures!
//	if (m_mode == MODE_NO_VT) glDisable(GL_TEXTURE_2D);

	for (itTri=m_triangleList.begin(); itTri!=m_triangleList.end(); itTri++) {
		(*itTri)->drawTriangle();
	}
}

/**
 * \brief quick and ugly function to draw the bounding box of an object
 */
void OBJObject::drawBoundingBox(void) {
	GLfloat thickness = 0.1f;
//	GLfloat color[] = {0.0f, 0.0f, 0.0f, 1.0f};
	GLfloat color[] = {1.0f, 1.0f, 0.0f, 1.0f};
//	glLineWidth(5.0);

	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
	glDisable(GL_TEXTURE_2D); 


	//parallel to x-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f(m_maxX, m_minY + (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX, m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_minX, m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_minX, m_minY + (thickness/2), m_minZ + (thickness/2)); 

		glNormal3f(0.0f, 0.0f, -1.0f);
		glVertex3f(m_minX, m_minY + (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX, m_minY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_maxX, m_minY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_maxX, m_minY + (thickness/2), m_minZ - (thickness/2)); 
		

		glNormal3f(0.0f, 1.0f, 0.0f);
		glVertex3f(m_minX, m_minY + (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX, m_minY + (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX, m_minY + (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX, m_minY + (thickness/2), m_minZ - (thickness/2)); 
		
		glNormal3f(0.0f, -1.0f, 0.0f);
		glVertex3f(m_minX, m_minY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX, m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX, m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX, m_minY - (thickness/2), m_minZ - (thickness/2)); 
	glEnd();
	
	//parallel to x-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f(m_maxX, m_minY + (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX, m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_minX, m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_minX, m_minY + (thickness/2), m_maxZ + (thickness/2)); 

		glNormal3f(0.0f, 0.0f, -1.0f);
		glVertex3f(m_minX, m_minY + (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX, m_minY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_maxX, m_minY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_maxX, m_minY + (thickness/2), m_maxZ - (thickness/2)); 
		

		glNormal3f(0.0f, 1.0f, 0.0f);
		glVertex3f(m_minX, m_minY + (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX, m_minY + (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX, m_minY + (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX, m_minY + (thickness/2), m_maxZ - (thickness/2)); 
		
		glNormal3f(0.0f, -1.0f, 0.0f);
		glVertex3f(m_minX, m_minY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX, m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX, m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX, m_minY - (thickness/2), m_maxZ - (thickness/2)); 
	glEnd();


	
	//parallel to x-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f(m_maxX, m_maxY + (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX, m_maxY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_minX, m_maxY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_minX, m_maxY + (thickness/2), m_minZ + (thickness/2)); 

		glNormal3f(0.0f, 0.0f, -1.0f);
		glVertex3f(m_minX, m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX, m_maxY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_maxX, m_maxY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_maxX, m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		

		glNormal3f(0.0f, 1.0f, 0.0f);
		glVertex3f(m_minX, m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX, m_maxY + (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX, m_maxY + (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX, m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		
		glNormal3f(0.0f, -1.0f, 0.0f);
		glVertex3f(m_minX, m_maxY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX, m_maxY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX, m_maxY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX, m_maxY - (thickness/2), m_minZ - (thickness/2)); 
	glEnd();
	
	//parallel to x-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f(m_maxX, m_maxY + (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX, m_maxY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_minX, m_maxY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_minX, m_maxY + (thickness/2), m_maxZ + (thickness/2)); 

		glNormal3f(0.0f, 0.0f, -1.0f);
		glVertex3f(m_minX, m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX, m_maxY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_maxX, m_maxY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_maxX, m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		

		glNormal3f(0.0f, 1.0f, 0.0f);
		glVertex3f(m_minX, m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX, m_maxY + (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX, m_maxY + (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX, m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		
		glNormal3f(0.0f, -1.0f, 0.0f);
		glVertex3f(m_minX, m_maxY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX, m_maxY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX, m_maxY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX, m_maxY - (thickness/2), m_maxZ - (thickness/2)); 
	glEnd();


	//next quads are all perpendicular to the ones above

	//parallel to z-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, -1.0f, 0.0f);
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_maxZ); 
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_maxZ); 
		
		glNormal3f(0.0f, 1.0f, 0.0f);
		glVertex3f(m_maxX - (thickness/2), m_minY + (thickness/2), m_maxZ); 
		glVertex3f(m_maxX - (thickness/2), m_minY + (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_minY + (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_minY + (thickness/2), m_maxZ); 
		
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_maxZ); 
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_minZ); 
		glVertex3f(m_maxX - (thickness/2), m_minY + (thickness/2), m_minZ); 
		glVertex3f(m_maxX - (thickness/2), m_minY + (thickness/2), m_maxZ); 
		
		glNormal3f(1.0f, 0.0f, 0.0f);
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_maxZ); 
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_minY + (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_minY + (thickness/2), m_maxZ); 

	glEnd();
	
	//parallel to z-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, -1.0f, 0.0f);
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_maxZ); 
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_maxZ); 
		
		glNormal3f(0.0f, 1.0f, 0.0f);
		glVertex3f(m_minX - (thickness/2), m_minY + (thickness/2), m_maxZ); 
		glVertex3f(m_minX - (thickness/2), m_minY + (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_minY + (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_minY + (thickness/2), m_maxZ); 
		
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_maxZ); 
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_minZ); 
		glVertex3f(m_minX - (thickness/2), m_minY + (thickness/2), m_minZ); 
		glVertex3f(m_minX - (thickness/2), m_minY + (thickness/2), m_maxZ); 
		
		glNormal3f(1.0f, 0.0f, 0.0f);
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_maxZ); 
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_minY + (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_minY + (thickness/2), m_maxZ); 

	glEnd();
	
	//parallel to z-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, -1.0f, 0.0f);
		glVertex3f(m_maxX - (thickness/2), m_maxY - (thickness/2), m_maxZ); 
		glVertex3f(m_maxX - (thickness/2), m_maxY - (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_maxY - (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_maxY - (thickness/2), m_maxZ); 
		
		glNormal3f(0.0f, 1.0f, 0.0f);
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_maxZ); 
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_maxZ); 
		
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(m_maxX - (thickness/2), m_maxY - (thickness/2), m_maxZ); 
		glVertex3f(m_maxX - (thickness/2), m_maxY - (thickness/2), m_minZ); 
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_minZ); 
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_maxZ); 
		
		glNormal3f(1.0f, 0.0f, 0.0f);
		glVertex3f(m_maxX + (thickness/2), m_maxY - (thickness/2), m_maxZ); 
		glVertex3f(m_maxX + (thickness/2), m_maxY - (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_minZ); 
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_maxZ); 

	glEnd();
	
	//parallel to z-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, -1.0f, 0.0f);
		glVertex3f(m_minX - (thickness/2), m_maxY - (thickness/2), m_maxZ); 
		glVertex3f(m_minX - (thickness/2), m_maxY - (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_maxY - (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_maxY - (thickness/2), m_maxZ); 
		
		glNormal3f(0.0f, 1.0f, 0.0f);
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_maxZ); 
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_maxZ); 
		
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(m_minX - (thickness/2), m_maxY - (thickness/2), m_maxZ); 
		glVertex3f(m_minX - (thickness/2), m_maxY - (thickness/2), m_minZ); 
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_minZ); 
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_maxZ); 
		
		glNormal3f(1.0f, 0.0f, 0.0f);
		glVertex3f(m_minX + (thickness/2), m_maxY - (thickness/2), m_maxZ); 
		glVertex3f(m_minX + (thickness/2), m_maxY - (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_minZ); 
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_maxZ); 

	glEnd();

	
	//parallel to y-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, 0.0f, -1.0f);
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_minZ + (thickness/2)); 
		
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_minZ + (thickness/2)); 
		
		glNormal3f(1.0f, 0.0f, 0.0f);
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_minZ + (thickness/2)); 
	glEnd();
	
	//parallel to y-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, 0.0f, -1.0f);
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_minZ + (thickness/2)); 
		
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_minZ + (thickness/2)); 
		
		glNormal3f(1.0f, 0.0f, 0.0f);
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_minZ - (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_minZ + (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_minZ + (thickness/2)); 
	glEnd();

	//parallel to y-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, 0.0f, -1.0f);
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_maxZ + (thickness/2)); 
		
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX - (thickness/2), m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_minX - (thickness/2), m_maxY + (thickness/2), m_maxZ + (thickness/2)); 
		
		glNormal3f(1.0f, 0.0f, 0.0f);
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_minX + (thickness/2), m_maxY + (thickness/2), m_maxZ + (thickness/2)); 
	glEnd();
	
	//parallel to y-axis
	glBegin(GL_QUADS);
		glNormal3f(0.0f, 0.0f, -1.0f);
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_maxZ + (thickness/2)); 
		
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_maxX - (thickness/2), m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX - (thickness/2), m_maxY + (thickness/2), m_maxZ + (thickness/2)); 
		
		glNormal3f(1.0f, 0.0f, 0.0f);
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_maxZ - (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_minY - (thickness/2), m_maxZ + (thickness/2)); 
		glVertex3f(m_maxX + (thickness/2), m_maxY + (thickness/2), m_maxZ + (thickness/2)); 
	glEnd();

	color[0] = 1.0f; color[1] = 1.0f; color[2] =  1.0f; color[3] = 1.0f;
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);

	glEnable(GL_TEXTURE_2D); 

/*	glBegin(GL_LINE_LOOP);
		glColor3f(0.0f, 1.0f, 0.0f);

		glVertex3f(m_minX, m_minY, m_minZ); 
		glVertex3f(m_maxX, m_minY, m_minZ);
		glVertex3f(m_maxX, m_maxY, m_minZ); 
		glVertex3f(m_minX, m_maxY, m_minZ);
	glEnd();
		
	glBegin(GL_LINE_LOOP);
		glVertex3f(m_maxX, m_minY, m_minZ); 
		glVertex3f(m_maxX, m_minY, m_maxZ);
		glVertex3f(m_maxX, m_maxY, m_maxZ); 
		glVertex3f(m_maxX, m_maxY, m_minZ);
	glEnd();
		
	glBegin(GL_LINE_LOOP);
		glVertex3f(m_maxX, m_minY, m_maxZ); 
		glVertex3f(m_minX, m_minY, m_maxZ);
		glVertex3f(m_minX, m_maxY, m_maxZ); 
		glVertex3f(m_maxX, m_maxY, m_maxZ);
	glEnd();
	
	glBegin(GL_LINE_LOOP);
		glVertex3f(m_minX, m_minY, m_maxZ); 
		glVertex3f(m_minX, m_minY, m_minZ);
		glVertex3f(m_minX, m_maxY, m_minZ); 
		glVertex3f(m_minX, m_maxY, m_maxZ);
	glEnd();
*/
}

void OBJObject::toggleSelected(void) {
	if (m_selected == 0) m_selected = 1;
	else m_selected = 0;
}

int OBJObject::testBBIntersection(float x, float y, float z) {
	if (x > m_maxX || x < m_minX) return 0;
	if (y > m_maxY || y < m_minY) return 0;
	if (z > m_maxZ || z < m_minZ) return 0;
	return 1;
}

